package com.gandong8.trace.tool.service.impl;

import com.gandong8.trace.tool.service.CacheService;
import com.gandong8.trace.tool.util.ProtoStuffUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.params.SetParams;

import java.nio.charset.StandardCharsets;

@Slf4j
@Service("jedisService")
public class JedisService implements CacheService {
    @Autowired(required = false) @Qualifier( "jedisPool" )
    //@Resource(name="jedisPool")
    private JedisPool jedisPool;

    @Override
    public <T> T getObj(String key) {
        return null;
    }

    @Override
    public <T> T getObj(String key, Class<T> clazz) {
        byte[] result = new byte[0];
        try (Jedis jedis = jedisPool.getResource()) {
            result = jedis.get(key.getBytes(StandardCharsets.UTF_8));
        } catch(Exception e) {
            log.error("getObj Exception, key={} ", key, e);
        }
        try {
            return ProtoStuffUtil.deserialize(result, clazz);
        } catch(Exception e) {
            log.warn("deserialize Exception ,result={} ", result, e);
        }
        return null;
    }

    @Override
    public <T> void setObj(String key, T obj, int expiredSeconds) {
        try (Jedis jedis = jedisPool.getResource()) {
            jedis.setex(key.getBytes(StandardCharsets.UTF_8), expiredSeconds, ProtoStuffUtil.serialize(obj));
        } catch(Exception e) {
            log.warn("setObj Exception, key={} ", key, e);
        }
    }

    @Override
    public void delObj(String key) {
        try (Jedis jedis = jedisPool.getResource()) {
            jedis.del(key.getBytes(StandardCharsets.UTF_8));
        } catch(Exception e) {
            log.warn("delObj Exception, key={} ", key, e);
        }
    }

    @Override
    public boolean tryLock(String key, int expiredSeconds) {
        String result = "";
        try (Jedis jedis = jedisPool.getResource()) {
            SetParams setParams = new SetParams();
            setParams.nx();
            setParams.ex(expiredSeconds);
            //result = jedis.set(key, "", "nx", "ex", expiredSeconds);
            result = jedis.set(key, "", setParams);
        } catch(Exception e) {
            log.warn("lock key Exception:{} ", key, e);
        }
        return "OK".equals(result);
    }

    @Override
    public void unlock(String key) {
        delObj(key);
    }
}
